package com.pachong.android.framework.web;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.pachong.android.baseuicomponent.CompState;
import com.pachong.android.baseuicomponent.fragment.BaseFragment;
import com.pachong.android.frameworkbase.utils.AppUtil;

/**
 * Created by Zoi.
 * E-mail：KyluZoi@gmail.com
 * 2016/7/28
 */
public class CommonWebview extends WebView {

    private BaseFragment mAttachFramgent;
    private CommonWebChromeClient mCommonWebChromeClient;

    public CommonWebview(Context context) {
        this(context, null);
    }

    public CommonWebview(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    /**
     * 通过外部调用初始化，初始化的时候传递宿主fragment
     *
     * @param attachFragment
     */
    public void init(BaseFragment attachFragment) {
        mAttachFramgent = attachFragment;
        if (mAttachFramgent == null) {
            throw new RuntimeException("CommonWebChromeClient attach fragment 不能为null");
        }
        clearCookies(getContext());
        WebSettings webSettings = this.getSettings();
        //设置支持JavaScript脚本
        webSettings.setJavaScriptEnabled(true);
        //设置可以访问文件
        webSettings.setAllowFileAccess(true);
        webSettings.setDatabaseEnabled(true);

        //使用localStorage则必须打开
        webSettings.setDomStorageEnabled(true);

        webSettings.setGeolocationEnabled(true);
        //webSettings.setGeolocationDatabasePath(dir);

        webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
        webSettings.setBlockNetworkImage(false);
        webSettings.setSupportZoom(true);
        webSettings.setBuiltInZoomControls(true);
        // webSettings.setDisplayZoomControls(false);
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
        String userAgentStr = webSettings.getUserAgentString() +
                " Author/Crawler" +
                " vcode/" + AppUtil.getVersionCode(getContext())+
                " vname/" + AppUtil.getVersionName(getContext());
        webSettings.setUserAgentString(userAgentStr);
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); // TODO CACHE_DEFAULT

        //设置WebViewClient
        this.setWebViewClient(new WebViewClient() {
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // 拦截html电话请求
                if (url.startsWith("tel:")) {
                    tel(view.getContext(), url);
                    return true;
                }

                Log.e("kyluzoi", "shouldOverrideUrlLoading  load url == " + url);
                if (isMyApi(url)) {
                    return true;
                }

                // CommonWebview.this.loadUrl(url);
                // 消耗掉这个事件。Android中返回True的即到此为止吧,事件就会不会冒泡传递了，我们称之为消耗掉
                // return true;
                return false;
            }

            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                if (getState() != CompState.EMPTY_ERROR && getState() != CompState.EMPTY_INVALID_NEWWORK) {
                    setState(CompState.DATA);
                }
            }

            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public void onLoadResource(WebView view, String url) {
                super.onLoadResource(view, url);
            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                super.onReceivedError(view, errorCode, description, failingUrl);
                Log.e("vivi", "  onReceivedError errorCode = " + errorCode + " description == " + description);
                // -2 网络断开，或者ERR_ADDRESS_UNREACHABLE
                // -5 Authentication via the proxy server was unsuccessful
                // -1 There was a network error.  请求数据过程中中断网络
                if (errorCode == -2 || errorCode == -5 || errorCode == -1) {
                    setState(CompState.EMPTY_INVALID_NEWWORK);
                }
            }

            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                super.onReceivedSslError(view, handler, error);
                handler.proceed();
            }

            @Override
            public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
                super.onReceivedHttpError(view, request, errorResponse);
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
            }
        });

        mCommonWebChromeClient = new CommonWebChromeClient(mAttachFramgent);
        this.setWebChromeClient(mCommonWebChromeClient);
        // 覆盖默认后退按钮的作用，替换成WebView里的查看历史页面
        this.setOnKeyListener(new OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if ((keyCode == KeyEvent.KEYCODE_BACK)
                            && CommonWebview.this.canGoBack()) {
                        CommonWebview.this.goBack();
                        return true;
                    }
                }
                return false;
            }
        });

        // 长按之后不会弹出复制、粘贴的选择
        this.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return true;
            }
        });

    }


    /**
     * 拨打电话
     *
     * @param context
     * @param tel
     */
    public static void tel(Context context, String tel) {
        if (!TextUtils.isEmpty(tel)) {
            Intent intent_phone = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + tel));
            intent_phone.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent_phone);
        }
    }

    private boolean isMyApi(String url) {
        // TODO  判断是否要拦截url
        return false;
    }

    private void clearCookies(Context context) {
        CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(context);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.removeAllCookie();
        cookieSyncMngr.sync();
    }

    void setState(CompState state) {
        mAttachFramgent.setState(state);
    }

    CompState getState() {
        return mAttachFramgent.getState();
    }


    public void onActivityResult(int requestCode, int resultCode, Intent dataIntent) {
        mCommonWebChromeClient.onActivityResult(requestCode, resultCode, dataIntent);
    }



    /**
     * 拼接调用js 接口的字符串， 并且调用
     *
     * e.g javascript:add('1', '22');
     *
     * @param functionName
     * @param args
     */
    public void callJsFunction(String functionName, String ...args) {
        String sentenceFormat = "javascript:%1s(%2s)";
        StringBuffer argStrBuf = new StringBuffer();
        if (args != null && args.length > 0) {
            for (String arg : args) {
                argStrBuf.append("'").append(arg).append("'").append(",");
            }
        }
        String argSentence = argStrBuf.toString();
        if (!TextUtils.isEmpty(argSentence)) {
            if (argSentence.endsWith(",")) {
                argSentence = argSentence.substring(0, argSentence.length() - 1);
            }
        }
        sentenceFormat = String.format(sentenceFormat, functionName, argSentence);
        loadUrl(sentenceFormat);
    }

}
